/*
 * Galaxium Messenger
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Text;
using System.Runtime;
using System.Runtime.InteropServices;

namespace Galaxium.Protocol.Msn
{
	public class CabExtract
	{
		[DllImport ("libgalaxium")]
		private static extern bool libgalaxium_cab_init ();

		[DllImport ("libgalaxium")]
		private static extern void libgalaxium_cab_destroy ();
		
		[DllImport ("libgalaxium", CharSet=CharSet.Auto)]
		private static extern bool libgalaxium_cab_extract (string filename, string output_dir);
		
		private static CabExtract _instance;
		private static string _path;
		
		private CabExtract ()
		{
			_path = Path.Combine (Path.GetTempPath (), "Galaxium");
		}
		
		~CabExtract ()
		{
			Cleanup ();
		}
		
		public static CabExtract Instance
		{
			get {
				if (_instance == null)
					_instance = new CabExtract ();
				return _instance;
			}
		}

		public string ExtractToDirectory (string filename)
		{
			string dir = GetTempPath ();
			if (!Directory.Exists (dir))
				Directory.CreateDirectory (dir);
			
			if (!libgalaxium_cab_init ())
			{
				Anculus.Core.Log.Warn ("Unable to initialize libgalaxium cab extract");
				return null;
			}
			
			if (!libgalaxium_cab_extract (filename, dir))
			{
				Anculus.Core.Log.Warn ("libgalaxium cab extract failed");
				return null;
			}
			
			libgalaxium_cab_destroy ();
			return dir;
		}
		
		public void Cleanup ()
		{
			if (Directory.Exists (_path))
				Directory.Delete (_path, true);
		}

		private static string GetTempPath ()
		{
			string dir = null;
			do {
				dir = Path.Combine (_path, CabExtract.GenerateRandomString ());
			} while (Directory.Exists (dir));
			
			if (dir.EndsWith (Path.DirectorySeparatorChar.ToString ()))
				dir = dir.Substring (0, dir.Length - 1);
			return dir;
		}
		
		private static string GenerateRandomString ()
		{
			StringBuilder sb = new StringBuilder();
			Random random = new Random (DateTime.Now.Millisecond);
			char c;
			for(int i=0; i<8; i++) {
				c = Convert.ToChar (Convert.ToInt32 (Math.Floor (26 * random.NextDouble () + 65))) ;
				sb.Append (c);
			}

			return sb.ToString ();
		}
	}
}